﻿using ExcelRename.Model;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ExcelRename
{
    public partial class FrmMain : Form
    {
        private Thread _thread;
        public FrmMain()
        {
            InitializeComponent();
        }

        private List<DataInfo> GetDataInfos(string fn)
        {
            List<DataInfo> dataInfos = new List<DataInfo>();
            IWorkbook workbook;
            using (FileStream file = new FileStream(fn, FileMode.Open, FileAccess.Read))
            {
                workbook = new XSSFWorkbook(file); // 如果是.xls则使用new HSSFWorkbook(file);  
            }

            ISheet sheet = workbook.GetSheetAt(0); // 假设我们读取第一个sheet  

            // 用于存储合并单元格区域的映射  
            Dictionary<CellRangeAddress, string> mergedCellMap = new Dictionary<CellRangeAddress, string>();

            // 遍历合并区域  
            for (int i = 0; i < sheet.NumMergedRegions; i++)
            {
                CellRangeAddress range = sheet.GetMergedRegion(i);
                // 假设我们只关心第一列和第二列的合并单元格  
                if (range.FirstColumn <= 1) // 检查列的范围  
                {
                    // 读取左上角单元格的值  
                    IRow row = sheet.GetRow(range.FirstRow);
                    if (row != null)
                    {
                        ICell cell = row.GetCell(range.FirstColumn); // 假设取第一列的值，也可以取第二列  
                        if (cell != null)
                        {
                            mergedCellMap[range] = cell.ToString(); // 将合并区域映射到其值  
                        }
                    }
                }
            }


            // 现在遍历所有单元格并打印值（考虑合并单元格）  
            //从第1行开始，0行是表头
            for (int rowIndex = 1; rowIndex <= sheet.LastRowNum; rowIndex++)
            {
                IRow row = sheet.GetRow(rowIndex);
                if (row != null)
                {
                    DataInfo dataInfo = new DataInfo();
                    for (int colIndex = 0; colIndex < row.LastCellNum; colIndex++)
                    {
                        ICell cell = row.GetCell(colIndex);
                        string cellValue = cell?.ToString() ?? ""; // 如果单元格为空，则默认为空字符串  

                        // 检查是否在合并单元格中但不是起始单元格  
                        foreach (var mergedRegion in mergedCellMap)
                        {
                            if (mergedRegion.Key.IsInRange(rowIndex, colIndex))
                            {
                                // 使用合并单元格的值覆盖当前单元格的值  
                                cellValue = mergedCellMap[mergedRegion.Key];
                                break;
                            }
                        }
                        if (colIndex == 0)
                        {
                            dataInfo.Number = cellValue;
                        }
                        else if (colIndex == 1)
                            dataInfo.ID = cellValue;
                        else if (colIndex == 2)
                            dataInfo.Count = int.Parse(cellValue);
                        else if (colIndex == 3)
                        {
                            dataInfo.Property = cellValue;
                            dataInfo.Property = dataInfo.Property.Replace("/", " ");
                            //把#号默认成没有 #号 就按数字抓
                            dataInfo.Property = dataInfo.Property.Replace("#", "");
                        }
                        else if (colIndex == 4)
                            //默认此列为店铺的名称
                            dataInfo.ShopName = cellValue;
                    }
                    dataInfos.Add(dataInfo);
                }
            }

            // 关闭工作簿（如果需要的话，因为在这个例子中工作簿在using块之外被创建）  
            workbook.Close();
            return dataInfos;
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            this.FormClosing += FrmMain_FormClosing;
            new TextBoxDragDrop(txtImagesPath);
            new TextBoxDragDrop(txtSavePath);
            new TextBoxDragDrop(txtExcelFileName, true, new List<string>() { ".xlsx" });
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_thread != null && _thread.IsAlive) _thread.Abort();
        }

        private void btnImagesPath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            if (dlg.ShowDialog() != DialogResult.OK) return;
            txtImagesPath.Text = dlg.SelectedPath;
        }

        private void btnExcelFileName_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Excel文件(*.xlsx)|*.xlsx";
            if (dlg.ShowDialog() != DialogResult.OK) return;
            txtExcelFileName.Text = dlg.FileName;
        }

        private void btnSavePath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            if (dlg.ShowDialog() != DialogResult.OK) return;
            txtSavePath.Text = dlg.SelectedPath;
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            string imagesPath = txtImagesPath.Text.Trim();
            if (!Directory.Exists(imagesPath))
            {
                MessageBox.Show("图片总文件夹不存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            string excelFileName = txtExcelFileName.Text.Trim();
            if (!File.Exists(excelFileName))
            {
                MessageBox.Show("Excel文件不存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            string savePath = txtSavePath.Text.Trim();
            if (!Directory.Exists(savePath))
            {
                MessageBox.Show("保存位置不存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            _thread = new Thread(workService);
            _thread.Start();
        }

        private void LogFileNotFound(string logfn, DataInfo obj)
        {
            List<string> lines = new List<string>();
            for (int i = 0; i < obj.Count; i++)
            {
                string line = $"{obj.ID}-{obj.Property} {obj.ShopName}";
                lines.Add(line);
            }
            File.AppendAllLines(logfn, lines, Encoding.UTF8);
        }
        private void workService()
        {
            try
            {
                string savePath = txtSavePath.Text.Trim();
                string logfn = Path.Combine(savePath, $"日志.txt");
                int logIndex = 1;
                while (File.Exists(logfn))
                {
                    logfn = Path.Combine(savePath, $"日志-{logIndex++}.txt");
                }

                string extension = rbtnPNG.Checked ? ".PNG" : ".JPG";
                foreach (Control control in this.Controls) control.Enabled = false;
                progressBar1.Enabled = true;
                this.Cursor = Cursors.WaitCursor;
                string imagesPath = txtImagesPath.Text.Trim();
                string excelFileName = txtExcelFileName.Text.Trim();


                string targetPath = Path.Combine(savePath, "软黑色");
                if (!Directory.Exists(targetPath)) Directory.CreateDirectory(targetPath);

                var dataInfos = GetDataInfos(excelFileName);

                string originalImagesPath = Path.Combine(imagesPath, "原图");
                if (!Directory.Exists(originalImagesPath))
                {
                    MessageBox.Show("原图文件夹不存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                //订单号 和 文件夹名称 相同 都是数字
                string[] folders = Directory.GetDirectories(imagesPath, "*.*", SearchOption.AllDirectories);
                Dictionary<string, string> dic = new Dictionary<string, string>();
                foreach (string folder in folders)
                {
                    string name = Path.GetFileName(folder);
                    string[] parts = name.Split(new[] { ',', '，', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    HashSet<string> hashSet = new HashSet<string>(parts);
                    foreach (var obj in dataInfos)
                    {
                        if (hashSet.Contains(obj.ID))
                        {
                            if (!dic.ContainsKey(obj.ID))
                            {
                                dic.Add(obj.ID, folder);
                            }
                        }
                    }
                }
                progressBar1.Value = 0;
                progressBar1.Minimum = 0;
                progressBar1.Maximum = dataInfos.Count;
                foreach (var obj in dataInfos)
                {
                    progressBar1.Value += 1;
                    //纯数字
                    //属性哪里如果出现#键也默认按产品ID抓图片
                    if (obj.IsNumber || obj.Property.Contains("#"))
                    {
                        if (dic.ContainsKey(obj.ID))
                        {
                            string path = dic[obj.ID];
                            if (Directory.Exists(path))
                            {
                                string fn = Path.Combine(path, obj.Variation + extension);
                                if (File.Exists(fn))
                                {
                                    for (int i = 1; i <= obj.Count; i++)
                                    {
                                        //物流单号,订单号,产品品牌-1.PNG
                                        string brandPath = Path.Combine(targetPath, obj.Brand);
                                        if (!Directory.Exists(brandPath)) Directory.CreateDirectory(brandPath);
                                        string newfn = Path.Combine(brandPath, $"{obj.Number},{obj.ID},{obj.Brand}{extension}");
                                        int index = 1;
                                        while (File.Exists(newfn))
                                        {
                                            newfn = Path.Combine(brandPath, $"{obj.Number},{obj.ID},{obj.Brand}-{index++}{extension}");
                                        }
                                        File.Copy(fn, newfn);
                                    }
                                }
                                else
                                    LogFileNotFound(logfn, obj);
                            }
                            else
                                LogFileNotFound(logfn, obj);
                        }
                        else
                            LogFileNotFound(logfn, obj);
                    }
                    else
                    {
                        //在原图下面找
                        string fn = Path.Combine(originalImagesPath, obj.Variation + extension);
                        if (File.Exists(fn))
                        {
                            for (int i = 1; i <= obj.Count; i++)
                            {
                                //物流单号,订单号,产品品牌-1.PNG
                                string brandPath = Path.Combine(targetPath, obj.Brand);
                                if (!Directory.Exists(brandPath)) Directory.CreateDirectory(brandPath);
                                string newfn = Path.Combine(brandPath, $"{obj.Number},{obj.ID},{obj.Brand}{extension}");
                                int index = 1;
                                while (File.Exists(newfn))
                                {
                                    newfn = Path.Combine(brandPath, $"{obj.Number},{obj.ID},{obj.Brand}-{index++}{extension}");
                                }
                                File.Copy(fn, newfn);
                            }
                        }
                        else
                        {
                            LogFileNotFound(logfn, obj);
                        }
                    }
                }
                SomeMethodInBackgroundThread("操作完成", MessageBoxIcon.Information);
            }
            catch (ThreadAbortException) { }
            catch (Exception ex)
            {
                SomeMethodInBackgroundThread(ex.Message, MessageBoxIcon.Warning);
            }
            finally
            {
                foreach (Control control in this.Controls) control.Enabled = true;
                this.Cursor = Cursors.Default;
            }
        }

        // 假设这是你的后台线程中的某个方法  
        private void SomeMethodInBackgroundThread(string message, MessageBoxIcon icon)
        {
            // ... 其他代码 ...  

            // 使用窗体的InvokeRequired属性来检查当前是否在主线程上  
            if (this.InvokeRequired) // 假设this是你的窗体或某个控件的引用  
            {
                // 使用Lambda表达式或匿名方法来定义要在UI线程上执行的代码  
                this.Invoke(new Action<string, MessageBoxIcon>(ShowMessageBoxOnUiThread), message, icon);
            }
            else
            {
                // 如果已经在主线程上，直接调用  
                ShowMessageBoxOnUiThread(message, icon);
            }
        }

        // 这个方法将在UI线程上执行  
        private void ShowMessageBoxOnUiThread(string message, MessageBoxIcon icon)
        {
            MessageBox.Show(message, "提示", MessageBoxButtons.OK, icon);
        }
    }
}
